package com.donovosoft.api.common;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;

import org.apache.commons.net.ftp.FTPClient;

import com.donovosoft.api.NetSender;
import com.donovosoft.api.exceptions.AuthenticationException;
import com.donovosoft.api.exceptions.PathNotFound;

public class FtpClient extends NetSender {

	/**
	 * 
	 */
	private static final long serialVersionUID = -8688236792785712917L;
	private FTPClient client;
	public boolean isPassive = false;
	public boolean isAnonymus = false;

	public FtpClient() {
		client = new FTPClient();
	}

	@Override
	public boolean login() throws AuthenticationException {
		// TODO Auto-generated method stub
		boolean f = false;
		try {
			if (this.getPort() < 1) {
				this.setPort(21);
			}
			client.connect(this.getHost(), this.getPort());
			if (this.isPassive) {
				client.enterRemotePassiveMode();
			}

			if (this.isAnonymus) {
				f = client.login("anonymous", "");
			} else {
				f = client.login(this.getUser(), this.getPassword());
			}
			if (!f) {
				throw new AuthenticationException("FTP Login incorrect");
			}
		} catch (AuthenticationException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				client.logout();
				client.disconnect();
				client = null;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return f;
	}

	@Override
	public void changeDir(String path) throws PathNotFound {
		// TODO Auto-generated method stub
		try {
			if (!client.changeWorkingDirectory(path)) {
				throw new PathNotFound("Impossible to change ftp to this path:"
						+ path);
			}
		} catch (PathNotFound e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public String[] listFiles() {
		// TODO Auto-generated method stub
		String[] l = null;
		try {
			l = client.listNames();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return l;
	}

	@Override
	public boolean deleteFile(String name) throws IOException {
		// TODO Auto-generated method stub
		boolean f = false;
		try {
			f = client.deleteFile(name);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return f;
	}

	@Override
	public boolean makeDir(String path) {
		// TODO Auto-generated method stub
		boolean f = false;
		try {
			f = client.makeDirectory(path);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return f;
	}

	@Override
	public boolean deleteDir(String path) {
		// TODO Auto-generated method stub
		boolean f = false;
		try {
			f = client.removeDirectory(path);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return f;
	}

	@Override
	public long getModificationTime(String path) throws PathNotFound {
		// TODO Auto-generated method stub
		long l = 0;
		try {
			SimpleDateFormat format = new SimpleDateFormat("YYYYMMDDhhmmss");
			l = format.parse(client.getModificationTime(path)).getTime();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return l;
	}

	@Override
	public String currentDir() {
		// TODO Auto-generated method stub
		String s = null;
		try {
			s = client.printWorkingDirectory();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return s;
	}

	@Override
	public boolean putFile(File stream) {
		// TODO Auto-generated method stub
		boolean f = false;
		try {
			client.appendFile(stream.getName(),
					new FileInputStream(stream.getAbsolutePath()));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return f;
	}

	@Override
	public OutputStream getFile(String name) {
		OutputStream stream = null;
		try {

			stream = new ByteArrayOutputStream();
			InputStream file = client.retrieveFileStream(name);
			byte[] buf = new byte[file.available()];
			int len;
			while ((len = file.read(buf)) > 0) {
				stream.write(buf, 0, len);
			}
			file.close();
			stream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return stream;
	}

	@Override
	public boolean logout() {
		boolean f = false;
		try {
			f = this.client.logout();
			this.client.disconnect();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return f;
	}

}
